package com.msb.bf;

import sun.misc.Contended;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

/**
 * @author: zhaoyi
 * @create: 2020-05-08 11:43
 * @description: cpu缓存行关于伪共享变量的实验
 * 是有一点区别，但有些情况也会出现不对齐还更优的时候，感觉一般真用你到这样玩
 **/

public class CacheLine {



    static class Entity {
        public volatile long x = 1L;
    }

    static class EntityPadding extends Entity {
        // 定义7个long类型变量，进行缓存行填充
        public long p1, p2, p3, p4, p5, p6, p7;
    }

    static class EntityContended {
        /**
         * Jdk8中引入了@sun.misc.Contended这个注解来解决缓存伪共享问题。
         * 使用此注解有一个前提，必须开启JVM参数-XX:-RestrictContended，此注解才会生效
         * BUT 实验的时候不管开不开感觉没印象
         */
        @Contended
        public volatile long x = 1L;
    }

    private static Entity[] entities = new Entity[4];
    private static EntityContended[] entityContents = new EntityContended[2];

    static {

        entities[0] = new Entity();
        entities[1] = new Entity();

        entities[2] = new EntityPadding();
        entities[3] = new EntityPadding();

        entityContents[0] = new EntityContended();
        entityContents[1] = new EntityContended();
    }

    public static void main(String[] args) throws InterruptedException {

        CountDownLatch latch = new CountDownLatch(2);
        CountDownLatch latch2 = new CountDownLatch(2);


        //前两个线程更改没有对齐的
        Thread thread1 = new Thread(() -> {
            for (int i = 1; i < Integer.MAX_VALUE; i++) {
                long x = entities[0].x;
                x += 1;

            }
            latch.countDown();
        }, "noPadding-1");

        Thread thread2 = new Thread(() -> {
            for (int i = 1; i < Integer.MAX_VALUE; i++) {
                long x = entities[1].x;
                x += 1;

            }
            latch.countDown();
        }, "noPadding-2");

        Thread thread3 = new Thread(() -> {
            for (int i = 1; i < Integer.MAX_VALUE; i++) {
                long x = entities[2].x;
                x += 1;
            }
            latch2.countDown();
        }, "Padding-1");

        Thread thread4 = new Thread(() -> {
            for (int i = 1; i < Integer.MAX_VALUE; i++) {
                long x = entities[3].x;
                x += 1;

            }
            latch2.countDown();
        }, "Padding-2");


        Thread thread5 = new Thread(() -> {
            for (int i = 1; i < Integer.MAX_VALUE; i++) {
                long x = entityContents[0].x;
                x += 1;

            }
        }, "Contended-1");

        Thread thread6 = new Thread(() -> {
            for (int i = 1; i < Integer.MAX_VALUE; i++) {
                long x = entityContents[1].x;
                x += 1;

            }
        }, "Contended-2");


        //运行纳秒值 不对齐1595668800
        long start1 = System.nanoTime();
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.print("不对齐");
        System.out.println(System.nanoTime() - start1);

        latch.await();
        //运行纳秒值 对齐后1479728500
        long start2 = System.nanoTime();
        thread3.start();
        thread4.start();
        thread3.join();
        thread4.join();
        System.out.print("对齐后");
        System.out.println(System.nanoTime() - start2);

        latch2.await();

        //运行纳秒值 注解后1335234000
        long start3 = System.nanoTime();
        thread5.start();
        thread6.start();
        thread5.join();
        thread6.join();
        System.out.print("注解后");
        System.out.println(System.nanoTime() - start3);


    }

}
